package xyz.heyaoshare.utils;

import cn.hutool.core.lang.tree.TreeUtil;
import xyz.heyaoshare.core.controller.system.menu.vo.resp.MenuTreeRespVO;
import xyz.heyaoshare.core.entity.system.Menu;
import xyz.heyaoshare.core.enums.system.menu.MenuOpenStyleEnum;
import xyz.heyaoshare.core.enums.system.menu.MenuStatusEnum;
import xyz.heyaoshare.core.enums.system.menu.MenuTypeEnum;

import java.util.*;

/**
 * 树工具类【基于hu-tool】
 * @author YueHe
 * @version 0.0.1
 * @since 2025/6/25 上午10:50
 */
public class TreeUtils extends TreeUtil {

    /**
     * 将菜单列表构建为树形结构的响应对象列表。
     *
     * @param menus 菜单列表，包含所有菜单项的数据。
     * @return 构建好的菜单树形结构响应对象列表，其中根节点列表位于返回值的顶层。
     */
    public static List<MenuTreeRespVO> buildMenuTree(List<Menu> menus) {
        if (CollUtils.isEmpty(menus)) return new ArrayList<>();

        // 初始化根节点列表和ID到节点的映射
        List<MenuTreeRespVO> rootMenuTreeNodes = new ArrayList<>();
        Map<Long, MenuTreeRespVO> idToMenuTreeNodeMap = new HashMap<>();

        // 遍历menus，转换每个Menu为MenuTreeRespVO，并初始化子菜单列表
        for (Menu menu : menus) {
            MenuTreeRespVO menuTreeNode = new MenuTreeRespVO()
                    .setId(menu.getId())
                    .setParentId(menu.getParentId())
                    .setName(menu.getName())
                    .setUrl(menu.getUrl())
                    .setAuthority(menu.getAuthority())
                    .setType(menu.getType())
                    .setTypeStr(MenuTypeEnum.getLabel(menu.getType()))
                    .setOpenStyle(menu.getOpenStyle())
                    .setOpenStyleStr(MenuOpenStyleEnum.getLabel(menu.getOpenStyle()))
                    .setIcon(menu.getIcon())
                    .setSort(menu.getSort())
                    .setStatus(menu.getStatus())
                    .setStatusStr(MenuStatusEnum.getLabel(menu.getStatus()))
                    .setChildren(new ArrayList<>()); // 初始化子菜单列表
            // 将节点添加到映射中
            idToMenuTreeNodeMap.put(menu.getId(), menuTreeNode);
            // 检查是否有父节点，没有则作为根节点
            Long parentId = menu.getParentId();
            if (parentId == null || !idToMenuTreeNodeMap.containsKey(parentId)) {
                rootMenuTreeNodes.add(menuTreeNode);
            } else {
                // 有父节点，添加到父节点的children中
                MenuTreeRespVO parentNode = idToMenuTreeNodeMap.get(parentId);
                if (parentNode != null) parentNode.getChildren().add(menuTreeNode);
            }
        }
        // 对根节点进行排序，处理 sort 为 0 或 null 的情况
        rootMenuTreeNodes.sort(Comparator.comparing(MenuTreeRespVO::getSort, Comparator.nullsLast(Comparator.naturalOrder())));
        // 递归对每个子节点进行排序
        for (MenuTreeRespVO node : rootMenuTreeNodes) {
            sortChildren(node.getChildren());
        }
        return rootMenuTreeNodes;
    }

    // 辅助方法：递归对子节点进行排序
    private static void sortChildren(List<MenuTreeRespVO> children) {
        if (children == null || children.isEmpty()) return;
        // 排序子节点
        children.sort(Comparator.comparing(MenuTreeRespVO::getSort, Comparator.nullsLast(Comparator.naturalOrder())));
        // 递归每个子节点
        for (MenuTreeRespVO child : children) {
            sortChildren(child.getChildren());
        }
    }

}